package com.system.member.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.system.common.model.LoginUser;
import com.system.common.utils.CommonUtil;
import com.system.common.utils.SysJwtUtil;
import com.system.member.adapter.Login3rdAdapter;
import com.system.member.domain.*;
import com.system.member.enums.BizCodeEnum;
import com.system.member.enums.EmailCheckEnum;
import com.system.member.enums.SendCodeEnum;
import com.system.member.req.UserRegisterReq;
import com.system.member.service.*;
import com.system.member.utils.JsonData;
import com.system.member.utils.RedisIdWorker;
import com.system.member.utils.UIDGenerator;
import com.system.member.utils.sendMessage.NetworkUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@RestController
@RequestMapping("/sys/user")
public class SysUserController {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private NotifyService notifyService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private RedisIdWorker redisIdWorker;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private FileService fileService;


    @Autowired
    private Login3rdAdapter login3rdAdapter;
    /**
     * 上传用户头像
     *
     * 默认最大是1M,超过则报错
     *
     * @param file 文件
     * @return
     */
    @PostMapping(value = "upload")
    public JsonData uploadUserImg(
            @RequestPart("file") MultipartFile file){

        String result = fileService.uploadUserImg(file);
        return result!=null? JsonData.buildSuccess(result):JsonData.buildResult(BizCodeEnum.FILE_UPLOAD_USER_IMG_FAIL);
    }

    /**
     * 发送验证码
     * 1、匹配图形验证码是否正常
     * 2、发送验证码
     *
     * @param to
     * @param captcha
     * @return
     */
    @GetMapping("send_code")
    public R sendCode(@RequestParam(value = "to",required = true) String to,
                      @RequestParam(value = "captcha",required = true) String captcha,
                      @RequestParam(value = "codeType",required = true) String codeType,
                      HttpServletRequest request){
        String key = getCaptchaKey(request);
        String cacheCaptcha = redisTemplate.opsForValue().get(key);
        System.out.println(key);

        //匹配图形验证码是否一样
        if(captcha !=null && cacheCaptcha !=null && captcha.equalsIgnoreCase(cacheCaptcha)){
            //成功
            redisTemplate.delete(key);
            notifyService.sendCode(codeType,to);
            return R.ok("发送短信成功");
        }else{
            return R.error("发送短信失败");
        }
    }


    @RequestMapping("register")
    public R register(@Validated @RequestBody UserRegisterReq req){
        R register = sysUserService.register(req);
        return register;
    }

    @RequestMapping("login")
    public R login( @RequestBody UserRegisterReq req){
        R login = sysUserService.login(req);
        return login;
    }

    /**
     * 获取缓存的key
     * @param request
     * @return
     */
    private String getCaptchaKey(HttpServletRequest request){
        String ip = CommonUtil.getIpAddr(request);
        String userAgent = request.getHeader("User-Agent");
        String key = "user-service:captcha:"+ CommonUtil.MD5(userAgent);
        return key;
    }


    @PostMapping("/list")
    public R list(@RequestBody PageBean pageBean){
        String query=pageBean.getQuery().trim();
        Page<SysUser> pageResult = sysUserService.page(new Page<>(pageBean.getPageNum(), pageBean.getPageSize()),new QueryWrapper<SysUser>().like(StringUtils.isNotEmpty(query),"username",query));
        List<SysUser> userList = pageResult.getRecords();
        for(SysUser user:userList){
            List<SysRole> roleList = sysRoleService.list(new QueryWrapper<SysRole>().inSql("id", "select role_id from sys_user_role where user_id=" + user.getId()));
            user.setSysRoleList(roleList);
        }
        Map<String,Object> resultMap=new HashMap<>();
        resultMap.put("userList",userList);
        resultMap.put("total",pageResult.getTotal());
        return R.ok(resultMap);
    }


    /**
     * 添加或者修改
     * @param sysUser
     * @return
     */
    @PostMapping("/save")
    public R save(@RequestBody SysUser sysUser){
        if(sysUser.getId()==null || sysUser.getId()==-1){
            sysUser.setCreateTime(new Date());
            sysUser.setId(UIDGenerator.next());
            sysUserService.save(sysUser);
        }else{
            sysUser.setUpdateTime(new Date());
            sysUserService.updateById(sysUser);
        }
        return R.ok();
    }

    /**
     * 根据id查询
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public R findById(@PathVariable(value = "id")long id){
        SysUser sysUser = sysUserService.getById(id);
        Map<String,Object> map=new HashMap<>();
        map.put("sysUser",sysUser);
        return R.ok(map);
    }

    /**
     * 验证邮箱
     * @param sysUser
     * @return
     */
    @PostMapping("/checkUserName")
    public R checkUserName(@RequestBody SysUser sysUser){
        if(sysUserService.getByEmail(sysUser.getEmail())==null){
            return R.ok();
        }else{
            return R.error();
        }
    }

    /**
     * 删除
     * @param ids
     * @return
     */
    @Transactional
    @PostMapping("/delete")
    public R delete(@RequestBody Long[] ids){
        sysUserService.removeByIds(Arrays.asList(ids));
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("user_id",ids));
        return R.ok();
    }


    /**
     * 更新status状态
     * @param id
     * @param status
     * @return
     */
    @GetMapping("/updateStatus/{id}/status/{status}")
    public R updateStatus(@PathVariable(value = "id")Integer id,@PathVariable(value = "status")String status){
        SysUser sysUser = sysUserService.getById(id);
        sysUser.setStatus(status);
        sysUserService.saveOrUpdate(sysUser);
        return R.ok();
    }

    /**
     * 用户角色授权
     * @param userId
     * @param roleIds
     * @return
     */
    @Transactional
    @PostMapping("/grantRole/{userId}")
    public R grantRole(@PathVariable("userId") Long userId,@RequestBody Long[] roleIds){
        List<SysUserRole> userRoleList=new ArrayList<>();
        Arrays.stream(roleIds).forEach(r -> {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setRoleId(r);
            sysUserRole.setUserId(userId);
            userRoleList.add(sysUserRole);
        });
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().eq("user_id",userId));
        sysUserRoleService.saveBatch(userRoleList);
        return R.ok();
    }

    @RequestMapping("/test/login")
    public R testLogin( @RequestBody UserRegisterReq req){
        QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<>();
        sysUserQueryWrapper.eq("phonenumber",req.getTo());
        SysUser one = sysUserService.getOne(sysUserQueryWrapper);
        LoginUser loginUser = new LoginUser();
        BeanUtils.copyProperties(one,loginUser);
        String token = SysJwtUtil.geneJsonWebToken(loginUser);
        System.out.println("token: "+token);
        // accessToken
        // accessToken的过期时间
        // UUID生成一个token
        //String refreshToken = CommonUtil.generateUUID();
        //redisTemplate.opsForValue().set(refreshToken,"1",1000*60*60*24*30);
        return R.ok(token);
    }

    //    刷新token的方案
//    @PostMapping("refresh_token")
//    public JsonData getRefreshToken(Map<String,Object> param){
//
//        //先去redis,找refresh_token是否存在
//        //refresh_token存在，解密accessToken
//        //重新调用JWTUtil.geneJsonWebToken() 生成accessToken
//        //重新生成refresh_token，并存储redis，设置30天过期时间
//        //返回给前端
//        return null;
//    }

    @GetMapping("/giteelogin")
    public R giteelogin(String code, String state){
        return login3rdAdapter.loginByGitee(code, state);
    }
}
